package com.example.book_recommend.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.book_recommend.dao.UserMapper;
import com.example.book_recommend.entity.*;
import com.example.book_recommend.pojo.AddRight;
import com.example.book_recommend.pojo.MyPage;
import com.example.book_recommend.pojo.VueResultInfo;
import com.example.book_recommend.pojo.token_info.TokenObj;
import com.example.book_recommend.pojo.token_info.TokenObj1;
import com.example.book_recommend.service.*;
import com.example.book_recommend.service.impl.ShiroServiceImpl;
import com.example.book_recommend.utils.ResultCode;
import com.example.book_recommend.utils.ResultFactory;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

@RestController
@EnableAutoConfiguration
@CrossOrigin
@RequestMapping("api/role")
public class RoleController {
    @Autowired
    RoleService roleService;

    @Autowired
    TokenService tokenService;

    @Autowired
    UserRoleService userRoleService;

    @Autowired
    PrivilegeService privilegeService;

    @Autowired
    UserService userService;

    @Autowired
    RolePrivilegeService rolePrivilegeService;

    @Autowired
    UserMapper userMapper;

    /**
     * 获取所有权限；
     * @param
     * @return
     */
    @RequestMapping("getAllRole")
//    @ApiOperation(value = "通过分页的方式获取所有role", notes = "通过分页的方式获取所有role", httpMethod = "POST")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "page", defaultValue = "0", required = true, paramType = "query", dataType = "Integer"),
//            @ApiImplicitParam(name = "size", defaultValue = "5", required = true, paramType = "query", dataType = "Integer")
//
//    })
    public VueResultInfo getAll(@RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null || token == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        List<Role> roleList = roleService.getRolesByPage(0, 100);
        System.out.println(roleList.get(0).toString());

        JSONArray jsonArray = new JSONArray();
        for(Role r : roleList){
            Integer[] ps = rolePrivilegeService.getPrivilegesByRole(r.getRoleId());
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("rightIndexes", ps);
            jsonObject.put("name", r.getName());
            jsonObject.put("roleId", r.getRoleId());
            jsonArray.add(jsonObject);
        }
        JSONObject jsonObject = new JSONObject();

        jsonObject.put("rights", jsonArray);

        return ResultFactory.buildSuccessResult(jsonObject);
    }

    /**
     * 参数传入json{roleId}即可；
     * 这里为了省事，没有对其他参数进行限制；
     * @param role
     * @return
     */
    @RequestMapping("getById")
    @ApiOperation(value = "通过roleId获取指定的role", notes = "不存在返回的data是null", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", defaultValue = "5", required = true, paramType = "query", dataType = "Integer"),
    })
    public VueResultInfo getByID(@RequestBody @Valid Role role, @RequestHeader("token") String token, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());

            return ResultFactory.buildFailResult(message);
        }
        SysToken sysToken = tokenService.findToken(token);
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        return ResultFactory.buildSuccessResult(roleService.getRoleById(role.getRoleId()));
    }

    /**
     * 新增一个角色；
     * 忽略传入的roleId，并且自动生成；
     * name和code必须传入，description可选；
     * @param role
     * @param bindingResult
     * @return
     */
    @RequestMapping("addRole")
    @ApiOperation(value = "添加一个role", notes = "即使传入roleId也会忽略，在插入数据库时自动生成", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", defaultValue = "管理员1", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "code", defaultValue = "admin1", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "description", defaultValue = "阿巴阿巴阿巴", required = false, paramType = "query", dataType = "String"),
    })
    public VueResultInfo add(@RequestBody @Valid Role role, @RequestHeader("token") String token, BindingResult bindingResult){
        if (bindingResult.hasErrors()) {
            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());

            return ResultFactory.buildFailResult(message);
        }
        SysToken sysToken = tokenService.findToken(token);
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        role.setRoleId(null);
        Date date = new Date();
        role.setCreated(date);
        role.setUpdated(date);
        return ResultFactory.buildSuccessResult("成功添加行数：" + String.valueOf(roleService.addRole(role)));
    }

    /**
     * 更新一个角色的信息；
     * 根据id进行更新，且只更新传入的字段；
     * @param role
     * @param bindingResult
     * @return
     */
    @RequestMapping("updateRole")
    @ApiOperation(value = "更新一个角色的信息", notes = "根据roleId进行更新，且只更新传入的字段", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", defaultValue = "5", required = true, paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "name", defaultValue = "new管理员name", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "code", defaultValue = "new code", required = false, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "description", defaultValue = "new 描述", required = false, paramType = "query", dataType = "String"),
    })
    public VueResultInfo update(@RequestBody Role role, @RequestHeader("token") String token, BindingResult bindingResult){
        Role role1 = roleService.getRoleById(role.getRoleId());
        if (role1 == null) {
            String message = "参数错误，详细信息[找不到对应的roleId]。";
            return ResultFactory.buildFailResult(message);
        }
        SysToken sysToken = tokenService.findToken(token);
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }


        Date date = new Date();
        role.setUpdated(date);
        roleService.updateRoleById(role);
        return ResultFactory.buildSuccessResult("成功！");
    }

    /**
     * 根据id删除一个角色；
     * 只需要传入roleId即可，其他字段自动忽略；
     * @param role
     * @param bindingResult
     * @return
     */
    @RequestMapping("delRole")
    @ApiOperation(value = "删除一个角色", notes = "根据roleId进行删除", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", defaultValue = "5", required = true, paramType = "query", dataType = "Integer"),
    })
    public VueResultInfo delete(@RequestBody Role role, @RequestHeader("token") String token, BindingResult bindingResult){
        Role role1 = roleService.getRoleById(role.getRoleId());
        if (role1 == null) {
            String message = "参数错误，详细信息[找不到对应的roleId]。";
            return ResultFactory.buildFailResult(message);
        }
        SysToken sysToken = tokenService.findToken(token);
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        userRoleService.updateUserRoleByRole(role1.getRoleId(), 1);
        rolePrivilegeService.deleteByRole(role1.getRoleId());
        roleService.deleteById(role1.getRoleId());
        return ResultFactory.buildSuccessResult("成功！");
    }

    /**
     * 为指定角色添加权限；
     *
     * @param
     * @return
     */
    @RequestMapping("addRight")
    @ApiOperation(value = "为指定角色添加权限", notes = "根据roleId进行权限的添加,传入的参数需要是一个数组", httpMethod = "POST")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", defaultValue = "5", required = true, paramType = "query", dataType = "Integer"),
            @ApiImplicitParam(name = "addRights", defaultValue = "9", required = true, paramType = "query", dataType = "Integer[]"),
    })
    public VueResultInfo addPrivilegesTo(@RequestBody AddRight addRight, @RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        int count = 0;
        Date date = new Date();
        Role role = roleService.getRoleById(addRight.getRoleId());
        if(role == null){
            return ResultFactory.buildFailResult("roleId 不存在！");

        }
        RolePrivilege rolePrivilege = new RolePrivilege();
        for(Integer right : addRight.getAddRights()){
            rolePrivilege.setPrivilegeId(right);
            rolePrivilege.setRoleId(role.getRoleId());
            rolePrivilege.setUpdated(date);
            rolePrivilege.setCreated(date);

            count += roleService.addPrivilege(rolePrivilege);
        }

        return ResultFactory.buildSuccessResult("插入的行数：" + String.valueOf(count));
    }

    /**
     * 获取角色权限集合;
     * @param tokenObj
     * @return
     */
    @RequestMapping("getRoleRights")
    public VueResultInfo getPrivilegesByRole(@RequestBody TokenObj tokenObj){
        SysToken sysToken = tokenService.findToken(tokenObj.getToken());
        if(sysToken == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);
        HashSet<Integer> hashSet = new HashSet<>();
        for (Integer roleInt : roles){
            Integer[] p = rolePrivilegeService.getPrivilegesByRole(roleInt);
            hashSet.addAll(Arrays.asList(p));
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("showRights", hashSet);
//        System.out.println();
        return ResultFactory.buildSuccessResult(jsonObject);
    }

    /**
     * 删除某角色的某权限;
     * @param
     * @return
     */
    @RequestMapping("delRoleRight")
    public VueResultInfo delRoleRight(@RequestBody JSONObject jsonObject, @RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }

        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }
        Integer roleId = (Integer) jsonObject.get("roleId");
        Integer delRight = (Integer) jsonObject.get("delRight");

        int c = rolePrivilegeService.delete(new RolePrivilegeKey(roleId, delRight));
        return ResultFactory.buildSuccessResult("影响的行数："+String.valueOf(c));
    }

    /**
     * 单纯滴获取所有权限;
     * @param
     * @return
     */
    @RequestMapping("getRights")
    public VueResultInfo getRights(@RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }

        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        return ResultFactory.buildSuccessResult(privilegeService.getRights());
    }

    /**
     * 删除用户的某角色;
     * @param
     * @return
     */
    @RequestMapping("deleteUserRole")
    public VueResultInfo deleteUserRole(@RequestBody JSONObject jsonObject, @RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }

        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }
        Integer userId = (Integer) jsonObject.get("userId");
        Integer roleId = (Integer) jsonObject.get("roleId");

        int c = userRoleService.delete(new UserRoleKey(userId, roleId));
        return ResultFactory.buildSuccessResult("影响的行数："+String.valueOf(c));
    }

    /**
     * 给用户添加某角色;
     * @param
     * @return
     */
    @RequestMapping("addUserRole")
    public VueResultInfo addUserRole(@RequestBody JSONObject jsonObject, @RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }

        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }
        Integer userId = (Integer) jsonObject.get("userId");
        Integer roleId = (Integer) jsonObject.get("roleId");

        Date date = new Date();
        int c = userRoleService.add(new UserRole(userId, roleId, date, date));
        return ResultFactory.buildSuccessResult("影响的行数："+String.valueOf(c));
    }

    /**
     * 获取所有用户（分页）；
     * @param
     * @return
     */
    @RequestMapping("getAllUsers")
    public VueResultInfo getAllUsers(@RequestBody JSONObject jsonObject, @RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null || token == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }

        Integer page = (Integer) jsonObject.get("page") == null ? 0 : (Integer) jsonObject.get("page");
        Integer size = (Integer) jsonObject.get("size") == null ? 50: (Integer) jsonObject.get("size");

        return ResultFactory.buildSuccessResult(userService.getUserByPage(page, size));
    }

    /**
     * 获取用户数目；
     * @param
     * @return
     */
    @RequestMapping("geUserNum")
    public VueResultInfo geUserNum(@RequestHeader("token") String token){
        SysToken sysToken = tokenService.findToken(token);
        if(sysToken == null || token == null){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
        }
        Integer uid = sysToken.getUserId();
        Integer[] roles =  userRoleService.getRolesByUser(uid);

        if(!Arrays.asList(roles).contains(0)){
            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问", null);
        }


        return ResultFactory.buildSuccessResult(userService.countNumber());
    }

    @RequestMapping("getRoleList")
    public VueResultInfo getRoleList(@RequestBody JSONObject jsonObject, @RequestHeader("token") String token){

        String username = jsonObject.getString("username");
        if(username==null){
            username = "%%";
        }else{
            username = "%"+username+"%";
        }
        Integer page = (Integer) jsonObject.getInteger("page");
        Integer size = (Integer) jsonObject.getInteger("size");
        Subject subject= SecurityUtils.getSubject();
        boolean a = subject.hasRole("admin");
        if(!a){
            return new VueResultInfo(1,"你没有这个权限，可怜可怜",null);
        }
        VueResultInfo vueResultInfo = new VueResultInfo(0,"查询成功",null);
        vueResultInfo.setData(userMapper.selectUserRoleSimple(page,size,username));
        return vueResultInfo;
    }

//    /**
//     * 获取用户的权限；
//     * 根据token查询出userId，然后查询对应的角色，之后查询对应的权限；
//     * @param tokenObj
//     * @param bindingResult
//     * @return
//     */
//    @RequestMapping("getRoleRights0")
//    @ApiOperation(value = "获取用户对应的权限", notes = "根据token查询出userId，然后查询对应的角色，之后查询对应的权限", httpMethod = "POST")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "token", defaultValue = "1ded704ce9ba546acc563f4c9ef0eb52", required = true, paramType = "query", dataType = "String"),
//    })
//    public VueResultInfo getRoleRights0(@RequestBody @Valid TokenObj tokenObj, BindingResult bindingResult){
//        if (bindingResult.hasErrors()) {
//            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
//
//            return ResultFactory.buildFailResult(message);
//        }
//
//        SysToken sysToken = tokenService.findToken(tokenObj.getToken());
//        if(sysToken == null){
//            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
//        }
//        Integer uid = sysToken.getUserId();
//
//        Integer[] roles =  userRoleService.getRolesByUser(uid);
//        Role[] roleList = new Role[roles.length];
//        int i = 0;
//        for (Integer roleInt : roles){
//            Role role1 = roleService.getRoleById(roleInt);
//            roleList[i] = role1;
//            i++;
//        }
//
//        return ResultFactory.buildSuccessResult(roleList);
//    }
//
//
//    @RequestMapping("getRoleRights")
//    @ApiOperation(value = "获取用户所有的角色", notes = "根据token查询出userId，然后查询对应的角色", httpMethod = "POST")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "token", defaultValue = "1ded704ce9ba546acc563f4c9ef0eb52", required = true, paramType = "query", dataType = "String"),
//    })
//    public VueResultInfo getRoleRights(@RequestBody @Valid TokenObj1 tokenObj, BindingResult bindingResult){
//        if (bindingResult.hasErrors()) {
//            String message = String.format("参数错误，详细信息[%s]。", Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
//
//            return ResultFactory.buildFailResult(message);
//        }
//
//        SysToken sysToken = tokenService.findToken(tokenObj.getToken());
//        if(sysToken == null){
//            return ResultFactory.buidResult(ResultCode.UNAUTHORIZED, "无权访问:尚未登录", null);
//        }
//        Integer uid = sysToken.getUserId();
//
//        Integer[] roles =  tokenObj.getRole_ids();
//        for(Integer role : roles){
//            UserRole userRole = userRoleService.getOne(uid, role);
//            if(userRole == null){
//                continue;
//            }
////            privilegeService.
//        }
//
//
//        Role[] roleList = new Role[roles.length];
//        int i = 0;
//        for (Integer roleInt : roles){
//            Role role1 = roleService.getRoleById(roleInt);
//            roleList[i] = role1;
//            i++;
//        }
//
//
//        return ResultFactory.buildSuccessResult(roleList);
//
//    }
}
